/////////////////////////////////////////////////////////////////////////////
// @doc
// @module BitTools.h | BitTools
//
// @normal Copyright (c) 2001 by Eduardo Velasquez
//
// Date:	Friday, December 21, 2001
//
///////////////

#if !defined(__BITTOOLS_H_89FD4A6F_C6C5_4726_8217_1F2BDDB98335__)
#define __BITTOOLS_H_89FD4A6F_C6C5_4726_8217_1F2BDDB98335__

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#if !defined(_LIMITS_)
#	include <limits>
#endif // !defined(_LIMITS_)


namespace bittools
{
	/////////////////////////////////////////////////////////////////////////////
	// Bit functions based on bitmask
	template<class T, class U>
	inline bool isAnyBitSet(T value, U mask)
	{
		return (value & mask) != 0;
	}

	template<class T, class U>
	inline bool areAllBitsSet(T value, U mask)
	{
		return (value & mask) == mask;
	}

	template<class T, class U>
	inline bool areAllBitsClear(T value, U mask)
	{
		return (value & mask) == 0;
	}

	template<class T, class U>
	inline T setBits(T value, U mask)
	{
		return value | mask;
	}

	template<class T, class U>
	inline T setBitsExcept(T value, U mask)
	{
		return value | ~mask;
	}

	template<class T, class U>
	inline T clearBits(T value, U mask)
	{
		return value & ~mask;
	}

	template <class T, class U>
	inline T clearBitsExcept(T value, U mask)
	{
		return value & mask;
	}

	template <class T, class U, class V>
	inline T setBits(T value, U mask, V bSet)
	{
		return bSet != 0 ? setBits(value, mask) : clearBits(value, mask);
	}

	template <class T, class U>
	inline T setClearBits(T value, U add, U remove)
	{
		return (value | add) & ~remove;
	}


	/////////////////////////////////////////////////////////////////////////////
	// Bit functions based on bit position
	template <class T>
	inline T setBitByPos(T value, unsigned char bit)
	{
		ASSERT(bit < std::numeric_limits<T>::digits);
		return value | (1 << bit);
	}

	template <class T>
	inline T clearBitByPos(T value, unsigned char bit)
	{
		ASSERT(bit < std::numeric_limits<T>::digits);
		return value & ~(1 << bit);
	}

	template <class T>
	inline bool isBitSetByPos(T value, unsigned char bit)
	{
		ASSERT(bit < std::numeric_limits<T>::digits);
		return (value & (1 << bit)) != 0;
	}

	template <class T>
	inline bool isBitClearByPos(T value, unsigned char bit)
	{
		return isBitSetByPos(value, bit) == false;
	}

};

#endif  // !defined(__BITTOOLS_H_89FD4A6F_C6C5_4726_8217_1F2BDDB98335__)
